package me.flyray.bsin.gateway;

import io.ipfs.api.IPFS;
import io.ipfs.api.MerkleNode;
import io.ipfs.api.NamedStreamable;
import io.ipfs.multihash.Multihash;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.junit.Test;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;



/**
 * ipfs http api test case
 * 1、参考： https://ipfs.docs.apiary.io/#reference/file/ls
 */
public class s11eDaoIpfs {

    private static String ipfHttpUrl = "http://127.0.0.1:5001/api/v0/";
//    private static String ipfHttpUrl = "http://114.116.93.253:5002/api/v0/";



    /**
     * ipfs http api： add
     * 1、添加单个文件，默认添加在"/ipfs/"目录下，添加后需要调用 cp或mv 接口赋值或者移动到指定的文件夹
     */
    @Test
    public void httpAdd() throws ClientProtocolException, IOException {
        RequestConfig defaultRequestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(3000)
                .setConnectionRequestTimeout(3000).build();

        CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();
        httpClient = HttpClients.createDefault();
        String url = ipfHttpUrl + "add";
        String filePath = "/home/leonard/code/metadata/2.txt";
        String fileName = "1.txt";
        HttpPost post = new HttpPost(url);
        // 设置超时时间
        post.setConfig(defaultRequestConfig);

        // 传文件
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        builder.addBinaryBody("file", new File(filePath), ContentType.DEFAULT_BINARY, fileName);
        builder.addTextBody("r", "true");
        post.setEntity(builder.build());

        ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
            public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
                int status = response.getStatusLine().getStatusCode();
                if (status >= 200 && status < 300) {
                    HttpEntity entity = response.getEntity();
                    return entity != null ? EntityUtils.toString(entity) : null;
                } else {
                    throw new ClientProtocolException("Unexpected response status: " + status);
                }
            }
        };

        System.out.println(httpClient.execute(post, responseHandler));
    }


    /**
     * ipfs http api： add
     * 1、添加多个文件，默认添加在"/ipfs/"目录下，添加后需要调用 cp或mv 接口赋值或者移动到指定的文件夹
     */
    @Test
    public void httpAddDir() throws ClientProtocolException, IOException {
        RequestConfig defaultRequestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(3000)
                .setConnectionRequestTimeout(3000).build();

        CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();
        httpClient = HttpClients.createDefault();
        String url = ipfHttpUrl + "add";
        String filePath = "/home/leonard/code/metadata/";
        String fileName1 = "2.json";
        String fileName2 = "2.png";
        HttpPost post = new HttpPost(url);
        // 设置超时时间
        post.setConfig(defaultRequestConfig);

        // 传文件
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        builder.addBinaryBody("file1", new File(filePath + fileName1), ContentType.DEFAULT_BINARY, fileName1);      //添加的文件1--file1
        builder.addBinaryBody("file2", new File(filePath + fileName2), ContentType.DEFAULT_BINARY, fileName2);      //添加的文件2--file2
        builder.addTextBody("r", "true");


        post.setEntity(builder.build());

        ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
            public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
                int status = response.getStatusLine().getStatusCode();
                if (status >= 200 && status < 300) {
                    HttpEntity entity = response.getEntity();
                    return entity != null ? EntityUtils.toString(entity) : null;
                } else {
                    throw new ClientProtocolException("Unexpected response status: " + status);
                }
            }
        };

        System.out.println(httpClient.execute(post, responseHandler));
    }


    /**
     * ipfs http api： files/mkdir
     * 1、创建问价夹
     */
    @Test
    public void httpMkdir() throws ClientProtocolException, IOException {
        RequestConfig defaultRequestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(3000)
                .setConnectionRequestTimeout(3000).build();

        CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();
        httpClient = HttpClients.createDefault();

        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

        //1、封装请求参数
        List<BasicNameValuePair> list = new ArrayList<BasicNameValuePair>();
        list.add(new BasicNameValuePair("arg", "/ipfsTest"));       // ipfsTest -- 文件夹路径
        list.add(new BasicNameValuePair("parents", "true"));        // 是否检查父目录

        //2、转化参数
        String params = EntityUtils.toString(new UrlEncodedFormEntity(list, Consts.UTF_8));
        System.out.println("***************mkdir params: " + params);
        //3、创建HttpGet请求
        String url = ipfHttpUrl + "files/mkdir";
        HttpPost post = new HttpPost(url + "?" + params);
        // 设置超时时间
        post.setConfig(defaultRequestConfig);
        post.setEntity(builder.build());

        ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
            public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
                int status = response.getStatusLine().getStatusCode();
                if (status >= 200 && status < 300) {
                    HttpEntity entity = response.getEntity();
                    return entity != null ? EntityUtils.toString(entity) : null;
                } else {
                    throw new ClientProtocolException("Unexpected response status: " + status);
                }
            }
        };

        System.out.println(httpClient.execute(post, responseHandler));
    }


    /**
     * ipfs http api： files/ls
     * 1、查看文件树结构
     */
    @Test
    public void httpLs() throws ClientProtocolException, IOException {
        RequestConfig defaultRequestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(3000)
                .setConnectionRequestTimeout(3000).build();

        CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();
        httpClient = HttpClients.createDefault();

        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

        //1、封装请求参数
        List<BasicNameValuePair> list = new ArrayList<BasicNameValuePair>();
        list.add(new BasicNameValuePair("arg", "/files"));      // files 查看的目录文件夹
        list.add(new BasicNameValuePair("l", "true"));
//        list.add(new BasicNameValuePair("flush", "true"));
        //2、转化参数
        String params = EntityUtils.toString(new UrlEncodedFormEntity(list, Consts.UTF_8));
        System.out.println(params);
        System.out.println("***************ls params: " + params);
        //3、创建HttpGet请求
        String url = ipfHttpUrl + "files/ls";
        HttpPost post = new HttpPost(url + "?" + params);
        // 设置超时时间
        post.setConfig(defaultRequestConfig);
        post.setEntity(builder.build());

        ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
            public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
                int status = response.getStatusLine().getStatusCode();
                if (status >= 200 && status < 300) {
                    HttpEntity entity = response.getEntity();
                    return entity != null ? EntityUtils.toString(entity) : null;
                } else {
                    throw new ClientProtocolException("Unexpected response status: " + status);
                }
            }
        };

        System.out.println(httpClient.execute(post, responseHandler));
    }


    /**
     * ipfs http api： files/cp
     * 1、文件拷贝
     */
    @Test
    public void httpCp() throws ClientProtocolException, IOException {
        RequestConfig defaultRequestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(3000)
                .setConnectionRequestTimeout(3000).build();

        CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();
        httpClient = HttpClients.createDefault();

        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

        //1、封装请求参数
        List<BasicNameValuePair> list = new ArrayList<BasicNameValuePair>();
        list.add(new BasicNameValuePair("arg", "/ipfs/QmXxf6xTZc5u6RepqAcEpLVt9BSqw6zsjbUeG6djdJd3am"));        // 要拷贝的文件
        list.add(new BasicNameValuePair("arg", "/ipfsTest/1.txt"));       //参数必须为arg    目标路径和文件名
//        list.add(new BasicNameValuePair("flush", "true"));        //optional
        //2、转化参数
        String params = EntityUtils.toString(new UrlEncodedFormEntity(list, Consts.UTF_8));
        System.out.println("***************cp params: " + params);
        //3、创建HttpGet请求
        String url = ipfHttpUrl + "files/cp";
        HttpPost post = new HttpPost(url + "?" + params);
        // 设置超时时间
        post.setConfig(defaultRequestConfig);
        post.setEntity(builder.build());

        ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
            public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
                int status = response.getStatusLine().getStatusCode();
                if (status >= 200 && status < 300) {
                    HttpEntity entity = response.getEntity();
                    return entity != null ? EntityUtils.toString(entity) : null;
                } else {
                    throw new ClientProtocolException("Unexpected response status: " + status);
                }
            }
        };

        System.out.println(httpClient.execute(post, responseHandler));
    }

    /**
     * ipfs http api： files/mv
     * 1、文件移动重命名-unix的mv指令一样功能
     */
    @Test
    public void httpMvFile() throws ClientProtocolException, IOException {
        RequestConfig defaultRequestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(3000)
                .setConnectionRequestTimeout(3000).build();

        CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();
        httpClient = HttpClients.createDefault();

        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

        //1、封装请求参数
        List<BasicNameValuePair> list = new ArrayList<BasicNameValuePair>();
        list.add(new BasicNameValuePair("arg", "/ipfs/2.txt"));         // 源文件路径和名称
        list.add(new BasicNameValuePair("arg", "/ipfsTest/1.txt"));     // 目标文件路径和名称
//        list.add(new BasicNameValuePair("flush", "true"));        //optional
        //2、转化参数
        String params = EntityUtils.toString(new UrlEncodedFormEntity(list, Consts.UTF_8));
        System.out.println("***************mv params: " + params);
        //3、创建HttpGet请求
        String url = ipfHttpUrl + "files/mv";
        HttpPost post = new HttpPost(url + "?" + params);
        // 设置超时时间
        post.setConfig(defaultRequestConfig);
        post.setEntity(builder.build());

        ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
            public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
                int status = response.getStatusLine().getStatusCode();
                if (status >= 200 && status < 300) {
                    HttpEntity entity = response.getEntity();
                    return entity != null ? EntityUtils.toString(entity) : null;
                } else {
                    throw new ClientProtocolException("Unexpected response status: " + status);
                }
            }
        };

        System.out.println(httpClient.execute(post, responseHandler));
    }

    /**
     * ipfs http api： files/mv
     * 1、文件移动重命名-unix的mv指令一样功能
     */
    @Test
    public void httpMv() throws ClientProtocolException, IOException {
        RequestConfig defaultRequestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(3000)
                .setConnectionRequestTimeout(3000).build();

        CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();
        httpClient = HttpClients.createDefault();

        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

        //1、封装请求参数
        List<BasicNameValuePair> list = new ArrayList<BasicNameValuePair>();
        list.add(new BasicNameValuePair("arg", "/files"));      // 源文件夹路径和名称
        list.add(new BasicNameValuePair("arg", "/filesMv"));    // 目标文件夹路径和名称
//        list.add(new BasicNameValuePair("flush", "true"));        //optional
        //2、转化参数
        String params = EntityUtils.toString(new UrlEncodedFormEntity(list, Consts.UTF_8));
        System.out.println("***************mv params: " + params);
        //3、创建HttpGet请求
        String url = ipfHttpUrl + "files/mv";
        HttpPost post = new HttpPost(url + "?" + params);
        // 设置超时时间
        post.setConfig(defaultRequestConfig);
        post.setEntity(builder.build());

        ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
            public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
                int status = response.getStatusLine().getStatusCode();
                if (status >= 200 && status < 300) {
                    HttpEntity entity = response.getEntity();
                    return entity != null ? EntityUtils.toString(entity) : null;
                } else {
                    throw new ClientProtocolException("Unexpected response status: " + status);
                }
            }
        };

        System.out.println(httpClient.execute(post, responseHandler));
    }


    /**
     * ipfs http api： files/publish
     * 1、Publish an object to IPNS
     * 2、将目标 CID 发布到 某一个 key 上
     */
    @Test
    public void httpPublish() throws ClientProtocolException, IOException {
        RequestConfig defaultRequestConfig = RequestConfig.custom().setSocketTimeout(500000).setConnectTimeout(300000)
                .setConnectionRequestTimeout(300000).build();

        CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();
        httpClient = HttpClients.createDefault();

        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

        //1、封装请求参数
        List<BasicNameValuePair> list = new ArrayList<BasicNameValuePair>();
        list.add(new BasicNameValuePair("arg", "/ipfs/QmQJUTe9B3bQvoCU8nZbCgMjWqw7tbb48YNZ6gC81usVRU"));        // 要发布的CID
        list.add(new BasicNameValuePair("key", "ipfsTest"));        //optional  发不到的 key
//        list.add(new BasicNameValuePair("resolve", "true"));        //optional
//        list.add(new BasicNameValuePair("lifetime", "time"));        //optional
//        list.add(new BasicNameValuePair("ttl", "time"));        //optional

        //2、转化参数
        String params = EntityUtils.toString(new UrlEncodedFormEntity(list, Consts.UTF_8));
        System.out.println("***************mv params: " + params);
        //3、创建HttpGet请求
        String url = ipfHttpUrl + "name/publish";
        HttpPost post = new HttpPost(url + "?" + params);
        // 设置超时时间
        post.setConfig(defaultRequestConfig);
        post.setEntity(builder.build());

        ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
            public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
                int status = response.getStatusLine().getStatusCode();
                if (status >= 200 && status < 300) {
                    HttpEntity entity = response.getEntity();
                    return entity != null ? EntityUtils.toString(entity) : null;
                } else {
                    throw new ClientProtocolException("Unexpected response status: " + status);
                }
            }
        };

        System.out.println(httpClient.execute(post, responseHandler));
    }



    /**
     * ipfs http api： files/resolve
     * 1、解析 IPNS 绑定的 CID
     */
    @Test
    public void httpResolve() throws ClientProtocolException, IOException {
        RequestConfig defaultRequestConfig = RequestConfig.custom().setSocketTimeout(50000).setConnectTimeout(30000)
                .setConnectionRequestTimeout(30000).build();

        CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();
        httpClient = HttpClients.createDefault();

        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

        //1、封装请求参数
        List<BasicNameValuePair> list = new ArrayList<BasicNameValuePair>();
        list.add(new BasicNameValuePair("arg", "/ipns/k51qzi5uqu5dh3669pqvx1zfgqajly99kszozdzyui8jkahl489zciwjhld4fn"));        // ipns地址
//        list.add(new BasicNameValuePair("recursive", "true"));        //optional
//        list.add(new BasicNameValuePair("nocache", "true"));        //optional

        //2、转化参数
        String params = EntityUtils.toString(new UrlEncodedFormEntity(list, Consts.UTF_8));
        System.out.println("***************mv params: " + params);
        //3、创建HttpGet请求
        String url = ipfHttpUrl + "name/resolve";
        HttpPost post = new HttpPost(url + "?" + params);
        // 设置超时时间
        post.setConfig(defaultRequestConfig);
        post.setEntity(builder.build());

        ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
            public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
                int status = response.getStatusLine().getStatusCode();
                if (status >= 200 && status < 300) {
                    HttpEntity entity = response.getEntity();
                    return entity != null ? EntityUtils.toString(entity) : null;
                } else {
                    throw new ClientProtocolException("Unexpected response status: " + status);
                }
            }
        };

        System.out.println(httpClient.execute(post, responseHandler));
    }


    /**
     * ipfs http api： key/list
     * 1、查看当前节点下的 key
     */
    @Test
    public void httpKeyList() throws ClientProtocolException, IOException {
        RequestConfig defaultRequestConfig = RequestConfig.custom().setSocketTimeout(50000).setConnectTimeout(30000)
                .setConnectionRequestTimeout(30000).build();

        CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();
        httpClient = HttpClients.createDefault();

        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

        //1、封装请求参数
        List<BasicNameValuePair> list = new ArrayList<BasicNameValuePair>();
//        list.add(new BasicNameValuePair("recursive", "true"));        //optional
//        list.add(new BasicNameValuePair("nocache", "true"));        //optional

        //2、转化参数
        String params = EntityUtils.toString(new UrlEncodedFormEntity(list, Consts.UTF_8));
        System.out.println("***************mv params: " + params);
        //3、创建HttpGet请求
        String url = ipfHttpUrl + "key/list";
        HttpPost post = new HttpPost(url + "?" + params);
        // 设置超时时间
        post.setConfig(defaultRequestConfig);
        post.setEntity(builder.build());

        ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
            public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
                int status = response.getStatusLine().getStatusCode();
                if (status >= 200 && status < 300) {
                    HttpEntity entity = response.getEntity();
                    return entity != null ? EntityUtils.toString(entity) : null;
                } else {
                    throw new ClientProtocolException("Unexpected response status: " + status);
                }
            }
        };

        System.out.println(httpClient.execute(post, responseHandler));
    }


    /**
     * ipfs http api： key/gen
     * 1、创建 key
     */
    @Test
    public void httpKeyGen() throws ClientProtocolException, IOException {
        RequestConfig defaultRequestConfig = RequestConfig.custom().setSocketTimeout(50000).setConnectTimeout(30000)
                .setConnectionRequestTimeout(30000).build();

        CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();
        httpClient = HttpClients.createDefault();

        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

        //1、封装请求参数
        List<BasicNameValuePair> list = new ArrayList<BasicNameValuePair>();
        list.add(new BasicNameValuePair("arg", "ipfsTest"));        // 要创建的 key 名称
//        list.add(new BasicNameValuePair("nocache", "true"));        //optional

        //2、转化参数
        String params = EntityUtils.toString(new UrlEncodedFormEntity(list, Consts.UTF_8));
        System.out.println("***************mv params: " + params);
        //3、创建HttpGet请求
        String url = ipfHttpUrl + "key/gen";
        HttpPost post = new HttpPost(url + "?" + params);
        // 设置超时时间
        post.setConfig(defaultRequestConfig);
        post.setEntity(builder.build());

        ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
            public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
                int status = response.getStatusLine().getStatusCode();
                if (status >= 200 && status < 300) {
                    HttpEntity entity = response.getEntity();
                    return entity != null ? EntityUtils.toString(entity) : null;
                } else {
                    throw new ClientProtocolException("Unexpected response status: " + status);
                }
            }
        };

        System.out.println(httpClient.execute(post, responseHandler));
    }
}


